﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
using System.Runtime.InteropServices;
using System.IO;

namespace LightEngine
{
    namespace Utilities
    {
        namespace FileSystem
        {
            /// <описание класса public class FileAssociation>
            /// Версия класса 1.0
            /// Автор(ы): Ушаков Михаил
            /// Класс предназначен для создания записей в реестре необходимых для связывания файлов с
            /// определенным расширением с исполняемым модулем(win/clr - приложением).
            /// Элементы класса:
            /// 1. Константы класса:
            ///    отсутствуют.
            /// 2. Поля класса:
            ///    отсутствуют.
            /// 3. Методы класса:
            /// а) public void AssociateFileType(String FileExtension,
            ///                                  String ProgramID, String Description,
            ///                                  String Application, UInt16 ResID) 
            ///    функция создающая ассоциацию файла с расширением String FileExtension с приложением
            ///    расположенным по абсолюному пути String Application, с именем String ProgramID и
            ///    описанием String Description, ResID - дескриптор win api ресурса, содержащего 
            ///    пиктограмму(иконку) которую будут носить ассоциируемые файлы. 
            ///    Записи в реестре создаются по следующим правилам:
            ///    - связывается ключ реестра(расширение файла) HKCR\.ext с иполняемым файлом ProgramID,
            ///    - создаются опции коммандной строки HKCR\FileExtension\Shell\Open\Command для открытия 
            ///    файла приложением, расположенным в String Application,
            ///    - создается иконка по умолчанию (изображение), связываемое с данным типом файла
            ///    HKCR\FileExtension\Shell\DefaultIcon из win api ресурса приложения, ResID его идентификатор.
            ///    Для правильного связывания требуется перезагрузка компьютера.
            /// б) public void DeleteAssociation(String RegKey) выполняет полное удаление ключа HKCR\RegKey
            ///    из реестра Windows, если такого ключа нет удаление не выполняется.
            /// в) public static Boolean IsAssociated(String Extension) функция проверяет существует ли 
            ///    ассоциация файлов с расширением Extension с каким-либо приложением, если существует возвращает 
            ///    true, в противном случае false.
            /// 4. Свойства и индексаторы класса:
            ///    отсутствуют.
            /// </описание класса public class FileAssociation>
            public class FileAssociation
            {
                public void AssociateFileType(String FileExtension,
                                              String ProgramID, String Description,
                                              String Application, UInt16 ResID)
                {
                    if (ProgramID == null || ProgramID == String.Empty) return;
                    using (RegistryKey FileExtKey = Registry.ClassesRoot.CreateSubKey(FileExtension))
                    {
                        FileExtKey.SetValue("", ProgramID);
                        if (Description != null && Description != String.Empty)
                            FileExtKey.SetValue("", Description);
                        if (Application != null && Application != String.Empty)
                            FileExtKey.CreateSubKey(@"Shell\Open\Command").SetValue("",
                                                    Application + " \"%1\"");

                        StringBuilder ResIcon = new StringBuilder(System.Windows.Forms.Application.ExecutablePath);
                        ResIcon.Insert(ResIcon.Length, ", 2");
                        FileExtKey.CreateSubKey("DefaultIcon").SetValue("", ResIcon.ToString());

                        FileExtKey.Close();
                    }
                }

                public void DeleteAssociation(String RegKey)
                {
                    Registry.ClassesRoot.DeleteSubKeyTree(RegKey);
                }

                public static Boolean IsAssociated(String Extension)
                {
                    return (Registry.ClassesRoot.OpenSubKey(Extension, false) != null);
                }

                /*[DllImport("Kernel32.dll")]
                private static extern uint GetShortPathName(String LongPath,
                                                            [Out] StringBuilder ShortPath, 
                                                            UInt32 BufferSize);

                private static String ToShortPathName(String LongName)
                {
                    StringBuilder StringBuf = new StringBuilder(PathLength);
                    UInt32 Size = (UInt32)StringBuf.Capacity;
                    UInt32 Ret = GetShortPathName(LongName, StringBuf, Size);
                    return StringBuf.ToString();
                }*/
            }
        }
    }
}
